home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
threads
/
ThreadsDynamicEnvironment.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-22
|
5KB
|
215 lines
/* begincopyright
Copyright (c) 1988 Xerox Corporation. All rights reserved.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
PCR Coordinator
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA 94304
endcopyright */
/*
* ThreadsDynamicEnvironment.c
* Copyright ╙ 1990 by Xerox Corporation. All rights reserved.
* Last changed by Pavel on May 24, 1990 6:20:34 pm PDT
*
* Edited by Demers, June 20, 1990 9:50:56 am PDT
*/
#include "xr/Threads.h"
#include "xr/ThreadsMsgPrivate.h"
#include "xr/ThreadsDynamicEnvironment.h"
XR_Pointer XR_UnwindFrameKey = (XR_Pointer) &XR_UnwindFrameKey;
int
XR_UnwindTo(target)
XR_DynFrame target;
{
XR_Pointer myKey = XR_UnwindFrameKey;
XR_DynFrame de = XR_GetDynamicEnvironment();
XR_DynFrame f;
for (f = de; (f != NIL) && (f != target); f = f->df_link)
;
if (f == NIL)
return -1;
for (f = de; f != target; f = f->df_link) {
if (f->df_key == myKey) {
XR_UnwindFrame uf = (XR_UnwindFrame) f;
XR_MesaProc unwinder = uf->uf_unwinder;
if (unwinder != NIL) {
XR_SetDynamicEnvironment(uf->uf_link);
(*(unwinder->mp_proc))(unwinder);
}
}
}
XR_SetDynamicEnvironment(target);
return 0;
}
int
XR_RewindTo(target)
XR_DynFrame target;
{
extern void DoRewind(/* end, f, key */);
XR_DynFrame de = XR_GetDynamicEnvironment();
XR_DynFrame f;
for (f = target; (f != NIL) && (f != de); f = f->df_link)
;
if (f == NIL)
return -1;
DoRewind(de, target, XR_UnwindFrameKey);
XR_SetDynamicEnvironment(target);
return 0;
}
#define REWIND_BATCH 32
static void
DoRewind(end, f, key) /* call all rewinders in (end..f] in that order */
XR_DynFrame end, f;
XR_Pointer key;
{
XR_DynFrame stack[REWIND_BATCH];
int i = 0;
for(;;) {
if( f == NIL ) XR_Panic("DoRewind 0");
if( f == end ) break;
if( f->df_key == key ) {
if( i == REWIND_BATCH ) {
DoRewind(end, f);
break;
} else {
stack[i] = f;
i++;
}
}
f = f->df_link;
}
while( i > 0 ) {
XR_UnwindFrame uf;
XR_MesaProc rewinder;
i -= 1;
uf = (XR_UnwindFrame)(stack[i]);
if( (rewinder = uf->uf_rewinder) != NIL ) {
XR_SetDynamicEnvironment(uf->uf_link);
(*(rewinder->mp_proc))(rewinder);
}
}
}
XR_DynFrame
XR_LookupInDynamicEnvironment(key, de)
XR_Pointer key;
XR_DynFrame de;
{
XR_DynFrame f;
void Damn();
for (f = de; f != NIL; f = f->df_link) {
if (((unsigned) f) & 0x3)
Damn(de);
if (f->df_key == key)
return f;
};
return NIL;
}
static void
Damn(de)
XR_DynFrame de;
{
XR_DynFrame f = de;
XR_PrintF("\nXR_LookupInDynamicEnvironment given a bad DE:\n");
for (;;) {
XR_PrintF("\t0x%x\n", f);
if (f == NIL || ((unsigned) f) & 0x3 != 0)
break;
f = f->df_link;
};
XR_CallDebugger(de);
}
static unsigned
EnvironmentLength(de)
XR_DynFrame de;
{
unsigned len = 0;
while (de != NIL) {
len++;
de = de->df_link;
};
return len;
}
XR_DynFrame
XR_FirstCommonParent(de1, de2)
XR_DynFrame de1, de2;
{
unsigned len1 = EnvironmentLength(de1);
unsigned len2 = EnvironmentLength(de2);
while (len1 > len2) {
de1 = de1->df_link;
len1--;
};
while (len2 > len1) {
de2 = de2->df_link;
len2--;
};
/* de1 and de2 are now the same length */
while (de1 != de2) {
de1 = de1->df_link;
de2 = de2->df_link;
};
return de1;
}
#undef XR_GetDynamicEnvironment
XR_DynFrame
XR_GetDynamicEnvironment()
{
return ((XR_DynFrame)(XR_currThread->t_dynEnv));
}
#undef XR_SetDynamicEnvironment
void
XR_SetDynamicEnvironment(f)
XR_DynFrame f;
{
XR_currThread->t_dynEnv = (XR_Pointer) f;
}